// Copyright (C) 2012 Volkov Zachar
// This file is part of the "zAxis Game Engine".
// For conditions of distribution and use, see copyright notice zx_Common.hpp

#include "zx_Async.hpp"
#include <Windows.h>

namespace zx {

//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
Mutex::Mutex( void )
{
      m_handle = new CRITICAL_SECTION;
      InitializeCriticalSection( (LPCRITICAL_SECTION)m_handle );
}
//----------------------------------------------------------------------------//
Mutex::~Mutex( void )
{
      LPCRITICAL_SECTION _cs = (LPCRITICAL_SECTION)m_handle;
      DeleteCriticalSection( _cs );
      delete _cs;
}
//----------------------------------------------------------------------------//
bool Mutex::Lock( int _time_ms )
{
     if( _time_ms == 0 )
     {
          return TryEnterCriticalSection( (LPCRITICAL_SECTION)m_handle ) != FALSE;
     }

     if( _time_ms < 0 )
     {
          EnterCriticalSection( (LPCRITICAL_SECTION)m_handle );
          return true;
     }

     DWORD _elapsed_time, _start_time = GetTickCount();

     bool _locked = false;

     while( true )
     {
          _elapsed_time = GetTickCount() - _start_time;
          _locked = false;

          if( ( _locked = TryEnterCriticalSection( (LPCRITICAL_SECTION)m_handle ) != FALSE ) || _elapsed_time >= static_cast< DWORD >( _time_ms ) )
          {
               return _locked;
          }

          Sleep( 1 );
     }

     return false;
}
//----------------------------------------------------------------------------//
void Mutex::Unlock( void )
{
      LeaveCriticalSection( (LPCRITICAL_SECTION)m_handle );
}
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//

} // namespace zx
